
#include <vector>
#include <sstream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <pthread.h>
volatile int ticket = 1000; // 抢票的票数

pthread_rwlock_t rwlock; // 定义读写锁

void *reader(void *arg)
{
    char *id = (char *)arg;
    while (1)
    {
        pthread_rwlock_rdlock(&rwlock);
        if (ticket <= 0)
        {
            pthread_rwlock_unlock(&rwlock);
            break;
        }
        printf("%s: %d\n", id, ticket);
        pthread_rwlock_unlock(&rwlock);
        usleep(1);
    }
    return nullptr;
}
void *writer(void *arg)
{
    char *id = (char *)arg;
    while (1)
    {
        pthread_rwlock_wrlock(&rwlock);
        if (ticket <= 0)
        {
            pthread_rwlock_unlock(&rwlock);
            break;
        }
        printf("%s: %d\n", id, --ticket);
        pthread_rwlock_unlock(&rwlock);
        usleep(1);
    }
    return nullptr;
}

struct ThreadAttr
{
    pthread_t tid;
    std::string id;
};

std::string create_reader_id(std::size_t i) // 给线程创建一个名字
{
    // 利用 ostringstream 进行 string 拼接
    std::ostringstream oss("thread reader ", std::ios_base::ate);
    oss << i;
    return oss.str();
}
std::string create_writer_id(std::size_t i) // 给线程创建一个名字
{
    // 利用 ostringstream 进行 string 拼接
    std::ostringstream oss("thread writer ", std::ios_base::ate);
    oss << i;
    return oss.str();
}
void init_readers(std::vector<ThreadAttr> &vec)
{
    for (std::size_t i = 0; i < vec.size(); ++i)
    {
        vec[i].id = create_reader_id(i);
        pthread_create(&vec[i].tid, nullptr, reader, (void *)vec[i].id.c_str());
    }
}
void init_writers(std::vector<ThreadAttr> &vec)
{
    for (std::size_t i = 0; i < vec.size(); ++i)
    {
        vec[i].id = create_writer_id(i);
        pthread_create(&vec[i].tid, nullptr, writer, (void *)vec[i].id.c_str());
    }
}
void join_threads(std::vector<ThreadAttr> const &vec)
{
    // 我们按创建的 逆序 来进行线程的回收
    for (std::vector<ThreadAttr>::const_reverse_iterator it = vec.rbegin(); it !=
                                                                            vec.rend();
         ++it)
    {
        pthread_t const &tid = it->tid;
        pthread_join(tid, nullptr);
    }
}
void init_rwlock()
{
#if 1
    // 写优先
pthread_rwlockattr_t attr;
pthread_rwlockattr_init(&attr);
pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
pthread_rwlock_init(&rwlock, &attr);
pthread_rwlockattr_destroy(&attr);
#else
    // 读优先，会造成写饥饿
    pthread_rwlock_init(&rwlock, nullptr);
#endif
}

int main()
{
    // 测试效果不明显的情况下，可以加大 reader_nr
    // 但也不能太大，超过一定阈值后系统就调度不了主线程了
    const size_t reader_nr = 1000; // 定义读者数目
    const size_t writer_nr = 2;    // 定义写者数目

    std::vector<ThreadAttr> readers(reader_nr); // 管理读者//初始化reader_nr个元素
    std::vector<ThreadAttr> writers(writer_nr); // 管理写者//初始化writer_nr个元素

    init_rwlock();         // 初始化读写锁
    init_readers(readers); // 初始化读者数组（创建读者线程）
    init_writers(writers); // 初始化写者数组（创建写者线程）

    join_threads(writers); // 等待全部写者线程
    join_threads(readers); // 等待全部读者线程

    pthread_rwlock_destroy(&rwlock); // 销毁读写锁
}